/**
 * 
 */
package com.xbang.core.dao.dynamic;

import java.lang.reflect.Field;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import com.xbang.core.dao.annotation.Dynamic;
import com.xbang.core.dao.support.GenericDaoSupport;

/**
 * @author dev.zhang
 *
 */
@Component
public class AnnotationDynamicDaoBeanPostProcessor implements BeanPostProcessor {

	private static final Log logger = LogFactory.getLog(AnnotationDynamicDaoBeanPostProcessor.class);
    
	@Autowired
	@Qualifier("genericDaoSupport")
	private GenericDaoSupport genericDaoSupport;
	
	/**
     * @param genericDaoSupport the genericDaoSupport to set
     */
    public void setGenericDaoSupport(GenericDaoSupport genericDaoSupport) {
        this.genericDaoSupport = genericDaoSupport;
    }
	
	/* (non-Javadoc)
     * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
     */
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        
    	Field[] fields = bean.getClass().getDeclaredFields();
        
    	for( Field field : fields ) {
    		if (field.isAnnotationPresent(Dynamic.class)) {
    			
    			logger.info("Inject DynamicDao Class ["  + field.getClass() + "] for: [ beanName: " + beanName + ", bean: " + bean.getClass() + "]");
    			
    			try {
    				Object dynamicDao = DynamicDaoFactory.create(field.getType(), genericDaoSupport);
        			
        			ReflectionUtils.makeAccessible(field);
        			ReflectionUtils.setField(field, bean, dynamicDao);
    			} catch(Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    	
        return bean;
    }
    
    /* (non-Javadoc)
     * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
     */
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

}
